package up7.biz;

import java.io.IOException;

import javax.servlet.jsp.PageContext;

import org.apache.commons.lang.StringUtils;

import com.google.gson.Gson;

import down3.biz.FolderBuilder;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import up7.database.DBConfig;
import up7.database.sql.SqlFile;
import up7.database.sql.SqlFolder;
import up7.model.FileInf;
import up7.sql.SqlExec;
import up7.sql.SqlParam;
import up7.sql.SqlWhereMerge;
import up7.utils.PathTool;
import up7.utils.WebBase;

public class PageFileMgr {
	PageContext m_pc;
	WebBase m_wb;
	
	public PageFileMgr(PageContext pc) throws IOException 
	{
		this.m_pc = pc;
		this.m_wb = new WebBase(pc);
		String page = this.m_wb.reqStr("page");
		
		String op = this.m_wb.reqStr("op");
			 if(StringUtils.equals("data", op)) this.load_data(false);		
		else if(StringUtils.equals("search", op)) this.load_data(false);
		else if(StringUtils.equals("rename", op)) this.rename();
		else if(StringUtils.equals("del", op)) this.del();
		else if(StringUtils.equals("del-batch", op)) this.del_batch();
		else if(StringUtils.equals("path", op)) this.build_path();
		else if(StringUtils.equals("mk-folder", op)) this.mk_folder();
		else if(StringUtils.equals("uncomp", op)) this.uncomp();
		else if(StringUtils.equals("uncmp-down", op)) this.uncmp_down();
		else if(StringUtils.equals("f_create", op)) this.f_create();
		else if(StringUtils.equals("fd_create", op)) this.fd_create();
		else if(StringUtils.equals("count", op)) this.fd_data_count();
		else if (!StringUtils.isEmpty(page) && StringUtils.isEmpty(op)) this.fd_data();
	}
	
	public void load_data(boolean toParam) {
		Integer pageSize = this.m_wb.reqInt("limit");
		Integer pageIndex = this.m_wb.reqInt("page");
		String pid = this.m_wb.reqStr("pid");
		pageSize = Math.max(pageSize, 20);
		pageIndex = Math.max(pageIndex, 1);
		
		SqlWhereMerge swm = new SqlWhereMerge();
		swm.equal("f_complete", 1);
		swm.equal("f_deleted", 0);
		swm.equal("f_fdChild", 1);
		swm.equal("f_pid", pid,false);//
		
		boolean isRoot = StringUtils.isEmpty(pid);//根目录
		if(isRoot) swm.equal("f_fdChild", 0);
		
		String where = swm.to_sql();
		
		SqlExec se = new SqlExec();
		JSONArray arr = se.page("up7_files"
				,"f_id"
				, "f_id,f_pid,f_nameLoc,f_sizeLoc,f_lenLoc,f_time,f_pidRoot,f_fdTask,f_pathSvr,f_pathRel"
				, pageSize
				, pageIndex
				, where
				, "f_fdTask desc,f_time desc");
		
		//加载目录表
		JSONArray folders = new JSONArray();
		if(!isRoot)
		{
			swm.del("f_fdChild");
			where = swm.to_sql();
			folders = se.page("up7_folders"
					, "f_id"
					, "f_id,f_nameLoc,f_pid,f_sizeLoc,f_time,f_pidRoot,f_pathRel"
					, pageSize
					, pageIndex
					, where
					, "f_time desc");
			
			for(int i = 0 ; i < folders.size() ; i++)
			{
				JSONObject fd = (JSONObject) folders.get(i);
				fd.put("f_fdTask", true);
				fd.put("f_fdChild", false);
				fd.put("f_pathSvr", "");
				
				arr.add(fd);
			}			
		}
		
		
		JSONObject o = new JSONObject();
		o.put("count", se.count("up7_files", where));
		o.put("code", 0);
		o.put("msg", "");
		o.put("data", arr);	
		
		if(toParam) this.m_wb.param.put("items", o);
		else this.m_wb.toContent(o);
	}
	public void search() {}
	public void rename() {
        String pid     = this.m_wb.reqStr("f_pid");
        String id      = this.m_wb.reqStr("f_id");
        String nameNew = this.m_wb.reqStr("f_nameLoc");
        nameNew = PathTool.url_decode(nameNew);
        boolean folder = this.m_wb.reqBool("f_fdTask");
        if (folder)
            this.rename_folder(pid,id,nameNew);
        else this.rename_file(pid,id, nameNew);     
	}


    void rename_file(String pid, String id, String name)
    {
        boolean ret = SqlFile.existSameFile(name, pid);
        if (ret)
        {
        	JSONObject v = new JSONObject();
        	v.put("state", false);
        	v.put("msg", "存在同名文件");
        	v.put("code", "102");
            //var v = new JObject { { "state",false},{ "msg","存在同名文件"},{ "code","102"} };
            this.m_wb.toContent(v);
        }
        else
        {
            SqlExec se = new SqlExec();
            //更新相对路径：/test/test.jpg
            JSONObject info = se.read("up7_files", "f_pathRel", new SqlParam[] {new SqlParam("f_id",id)});
            String pathRel = info.getString("f_pathRel");
            Integer pos = pathRel.lastIndexOf('/');
            pathRel = pathRel.substring(0, pos+1);
            pathRel = pathRel.concat(name);
            
            //更新名称
            se.update("up7_files",
                new SqlParam[] {
                    new SqlParam("f_nameLoc",name),
                    new SqlParam("f_nameSvr",name),
                    new SqlParam("f_pathRel",pathRel)
                },
                new SqlParam[] {
                    new SqlParam("f_id",id)
                }
                );

        	JSONObject v = new JSONObject();
        	v.put("state", true);
            this.m_wb.toContent(v);
        }
    }

    void rename_folder(String pid,String id,String name) {
        boolean ext = DbFolder.existSameFolder(name, pid);
        if(ext)
        {
        	JSONObject v = new JSONObject();
        	v.put("state", false);
        	v.put("msg", "存在同名目录");
        	v.put("code", "102");
            this.m_wb.toContent(v);
        }
        else
        {
            //取pathRoot=/test，并构造新路径
            String pathRelNew = DbFolder.getPathRel(id);
            String pathRelOld = pathRelNew;//旧的路径,pathRoot=/test
            Integer index = pathRelNew.lastIndexOf('/');
            pathRelNew = pathRelNew.substring(0, index + 1);
            pathRelNew = pathRelNew + name;

            //更新文件名称
            SqlExec se = new SqlExec();
            if(StringUtils.isEmpty(pid) )//根目录
            {
                se.update("up7_files",
                    new SqlParam[] {
                    new SqlParam("f_nameLoc",name),
                    new SqlParam("f_nameSvr",name)
                    },
                    new SqlParam[] {
                    new SqlParam("f_id",id)
                    }
                    );

                //更新文件夹路径
                se.update("up7_files", new SqlParam[] {
                    new SqlParam("f_pathRel",pathRelNew)
                },
                new SqlParam[] {
                    new SqlParam("f_id",id)
                }
                );
            }
            else
            {
                se.update("up7_folders",
                    new SqlParam[] {
                    new SqlParam("f_nameLoc",name),
                    },
                    new SqlParam[] {
                    new SqlParam("f_id",id)
                    }
                    );

                //更新文件夹路径
                se.update("up7_folders", new SqlParam[] {
                    new SqlParam("f_pathRel",pathRelNew)
                },
                new SqlParam[] {
                    new SqlParam("f_id",id)
                }
                );
            }
            
            DBConfig dc = new DBConfig();
            dc.db().updatePathRel(pathRelOld, pathRelNew);
            dc.folder().updatePathRel(pathRelOld, pathRelNew);

            JSONObject v = new JSONObject();
            v.put("state", true);
            this.m_wb.toContent(v);
        }
    }
	
	public void del() {
		String id = this.m_wb.reqStr("id");
		
		SqlExec se = new SqlExec();
		se.update("up7_files", 
				new SqlParam[] {new SqlParam("f_deleted",true)}, 
				new SqlParam[] {
						new SqlParam("f_id",id),
						new SqlParam("f_pid",id),
						new SqlParam("f_pidRoot",id)
				},
				"or");
		se.update("up7_folders", 
				new SqlParam[] {new SqlParam("f_deleted",true)}, 
				new SqlParam[] {
						new SqlParam("f_id",id),
						new SqlParam("f_pid",id),
						new SqlParam("f_pidRoot",id)
				},
				"or");
		
		JSONObject ret = new JSONObject();
		ret.put("ret", 1);
		this.m_wb.toContent(ret);		
		
	}
	public void del_batch() {
		
		String data = this.m_pc.getRequest().getParameter("data");
		data = PathTool.url_decode(data);
		JSONArray o = JSONArray.fromObject(data);
		
		SqlExec se = new SqlExec();
		se.exec_batch("up7_files", "update up7_files set f_deleted=1 where f_id=?", "", "f_id", o);
		se.exec_batch("up7_folders", "update up7_folders set f_deleted=1 where f_id=?", "", "f_id", o);
		
		JSONObject ret = new JSONObject();
		ret.put("ret", 1);
		this.m_wb.toContent(ret);
		
	}

    /// <summary>
    /// 生成导航路径
    /// </summary>
    void build_path()
    {
        String data = this.m_wb.reqStr("data");
        data = PathTool.url_decode(data);
        JSONObject fd = JSONObject.fromObject(data);

        DbFolder df = new DbFolder();
        this.m_wb.toContent(df.build_path(fd));
    }
	
	void mk_folder() throws IOException
    {
        String pid = this.m_wb.reqStr("f_pid");
        String pathRel = this.m_wb.reqStr("f_pathRel");
        pathRel = PathTool.url_decode(pathRel);
        String nameLoc = this.m_wb.reqStr("f_nameLoc");
        nameLoc = PathTool.url_decode(nameLoc);

        //存在同名文件
        if (DbFolder.existSameFolder(nameLoc, pid))
        {
        	JSONObject ret = new JSONObject();
        	ret.put("state", false);
        	ret.put("msg", "存在同名文件");
        	this.m_wb.toContent(ret);            
            return;
        }

        SqlExec se = new SqlExec();
        String guid = PathTool.guid();

        //根目录
        if (StringUtils.isEmpty(pid))
        {
            se.insert("up7_files", new SqlParam[] {
        new SqlParam("f_id",guid)
        ,new SqlParam("f_pid","")
        ,new SqlParam("f_pidRoot","")
        ,new SqlParam("f_pathRel",PathTool.combine(pathRel,nameLoc))
        ,new SqlParam("f_nameLoc",nameLoc)
        ,new SqlParam("f_complete",true)
        ,new SqlParam("f_fdTask",true)
        });
        }//子目录
        else
        {
            se.insert("up7_folders", new SqlParam[] {
        new SqlParam("f_id",guid)
        ,new SqlParam("f_pid",pid)
        ,new SqlParam("f_pidRoot","")
        ,new SqlParam("f_pathRel",PathTool.combine(pathRel,nameLoc))
        ,new SqlParam("f_nameLoc",nameLoc)
        ,new SqlParam("f_complete",true)
        });
        }
        
    	JSONObject o = new JSONObject();
    	o.put("state", true);
    	o.put("f_id", guid);
        o.put("f_pathRel", pathRel);
    	this.m_wb.toContent(o);
    }
	
	public void uncomp() {

        SqlExec se = new SqlExec();
        JSONArray files = se.exec("up7_files"
            , "select f_id as id,f_nameLoc as nameLoc,f_pathLoc as pathLoc,f_sizeLoc as sizeLoc,f_lenSvr as lenSvr,f_perSvr as perSvr,f_fdTask as fdTask from up7_files where f_complete=0 and f_fdChild=0 and f_deleted=0"
            , "f_id,f_nameLoc,f_pathLoc,f_sizeLoc,f_lenSvr,f_perSvr,f_fdTask"
            , "id,nameLoc,pathLoc,sizeLoc,lenSvr,perSvr,fdTask");
        this.m_wb.toContent( files );
	}
	public void uncmp_down() {

		String uid = this.m_pc.getRequest().getParameter("uid");
        SqlExec se = new SqlExec();
        JSONArray files = se.select("down3_files"
            , "f_id,f_nameLoc,f_pathLoc,f_perLoc,f_sizeSvr,f_fdTask"
            , new SqlParam[] {new SqlParam("f_uid",uid)}
            , ""
            );
        this.m_wb.toContent( files );
	}
	

    /// <summary>
    /// 初始化，同名文件验证
    /// </summary>
    void f_create() throws IOException
    {
        String pid      = this.m_wb.reqStr("pid");
        String pidRoot  = this.m_wb.reqStr("pidRoot");
        String md5      = this.m_wb.reqStr("md5");
        String id       = this.m_wb.reqStr("id");
        String uid      = this.m_wb.reqStr("uid");
        long lenLoc   	= this.m_wb.reqLong("lenLoc");
        String sizeLoc  = this.m_wb.reqStr("sizeLoc");
        String callback = this.m_wb.reqStr("callback");//jsonp参数
        //客户端使用的是encodeURIComponent编码，
        String pathLoc  = PathTool.url_decode(this.m_wb.reqStr("pathLoc"));//utf-8解码
        String pathRel  = this.m_wb.reqStr("pathRel");
        pathRel 		= PathTool.url_decode(pathRel);

        //参数为空
        if (   StringUtils.isEmpty(sizeLoc))
        {   
            this.m_wb.toContent(callback + "({\"value\":null})");
            return;
        }

        FileInf fileSvr = new FileInf();
        fileSvr.uid = uid;//将当前文件UID设置为当前用户UID
        fileSvr.id = id;
        fileSvr.pid = pid;
        fileSvr.fdChild = !StringUtils.isEmpty(pid);
        fileSvr.pidRoot = pidRoot;
        fileSvr.nameLoc = PathTool.getName(pathLoc);
        fileSvr.pathLoc = pathLoc;
        fileSvr.pathRel = PathTool.combine(pathRel, fileSvr.nameLoc);
        fileSvr.lenLoc = lenLoc;
        fileSvr.sizeLoc = sizeLoc;
        fileSvr.deleted = false;
        fileSvr.md5 = md5;
        fileSvr.nameSvr = fileSvr.nameLoc;

        //所有单个文件均以uuid/file方式存储
        PathGuidBuilder pb = new PathGuidBuilder();
        fileSvr.pathSvr = pb.genFile(fileSvr);

        //同名文件检测
        if (SqlFile.existSameFile(fileSvr.nameLoc, fileSvr.pid))
        {
            String data = callback + "({'value':'','ret':false,'code':'101'})";
            this.m_wb.toContent(data);
            return;
        }
        
        //
        SqlFile df = new SqlFile();
        df.add(fileSvr);        

        //触发事件
        up7_biz_event.file_create(fileSvr);
        

		Gson gson = new Gson();
		String json = gson.toJson(fileSvr);
		json = PathTool.url_encode(json);
		json = callback + "({\"value\":\"" + json + "\",\"ret\":true})";//返回jsonp格式数据。
		this.m_wb.toContent(json);
    }

    void fd_create() throws IOException
    {
        String pid       = this.m_wb.reqStr("pid");
        String id       = this.m_wb.reqStr("id");
        String pathLoc  = this.m_wb.reqStr("pathLoc");
        String sizeLoc  = this.m_wb.reqStr("sizeLoc");
        long lenLoc   = this.m_wb.reqLong("lenLoc");
        String uid       = this.m_wb.reqStr("uid");
        Integer fCount   = this.m_wb.reqInt("filesCount");
        String pathRel  = PathTool.url_decode(this.m_wb.reqStr("pathRel"));
        String callback = this.m_wb.reqStr("callback");
        pathLoc         = PathTool.url_decode(pathLoc);

        FileInf f = new FileInf();
        f.nameLoc = PathTool.getName(pathLoc);
        f.nameSvr = f.nameLoc;
        f.fdChild = !StringUtils.isEmpty(pid);
        f.id = id;
        f.pid = pid;
        f.pathLoc = pathLoc;
        f.sizeLoc = sizeLoc;
        f.lenLoc = lenLoc;
        f.fileCount = fCount;
        f.pathRel = PathTool.combine(pathRel,f.nameLoc);
        f.fdTask = true;
        f.uid = uid;
        //生成路径，格式：upload/年/月/日/guid/文件夹名称
        PathGuidBuilder pb = new PathGuidBuilder();
        f.pathSvr = pb.genFolder(f.uid, f.id,f.nameLoc);
        f.pathSvr = f.pathSvr.replace("\\", "/");
        PathTool.mkdir(f.pathSvr);

        //添加到队列表
        DBConfig cfg = new DBConfig();
        SqlFile db = cfg.db();
        db.add(f);

        //添加到文件夹表
        SqlFolder dbf = new SqlFolder();
        dbf.add(f);

        //触发事件
        up7_biz_event.folder_create(f);

		Gson gson   = new Gson();
		String json = gson.toJson(f);
		json        = PathTool.url_encode(json);
		json        = callback + "({\"value\":\"" + json + "\"})";//返回jsonp格式数据。
		this.m_wb.toContent(json);
    }

    void fd_data_count()
    {
        String id = this.m_wb.reqStr("id");
        if (StringUtils.isEmpty(id))
        {
            //Response.StatusCode = 500;
            //Response.StatusDescription = "id param is null";
            return;
        }

        FolderBuilder fb = new FolderBuilder();
        Integer c = fb.count(id);
        long totalSz = fb.totalSize(id);
    	JSONObject obj = new JSONObject();
    	obj.put("count", c);
    	obj.put("totalSize", totalSz);

        this.m_wb.toContent(obj);
    }


    /// <summary>
    /// 获取文件夹结构（JSON）
    /// 格式：
    /// [
    ///   {nameLoc,pathSvr,pathRel,lenSvr,sizeSvr}
    ///   {nameLoc,pathSvr,pathRel,lenSvr,sizeSvr}
    /// ]
    /// </summary>
    void fd_data()
    {
    	String id = this.m_wb.reqStr("id");
    	Integer page = this.m_wb.reqInt("page");

        if (StringUtils.isEmpty(id)) {        	
            //Response.StatusCode = 500;
            //Response.StatusDescription = "id param is null";
            return;
        }

        FolderBuilder fb = new FolderBuilder();
        String json = fb.build(page, id);
        json = PathTool.url_encode(json);
        this.m_wb.toContent(json);
    }
}